package org.ourguy.mymoviesandshows.datamodel;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;

import android.graphics.Bitmap;

/**
 * Episode abstract data type.
 * @author bordjukov
 */
public class Episode implements IWatchable, IFavoritable, Comparable<Episode> {

	/**
	 * The consecutive number of the episode in the season
	 */
	private int number;
	
	/**
	 * The season number of the episode
	 */
	private int seasonNumber;
	
	/**
	 * The ID of the series to which this episode belongs
	 */
	private String seriesId;
	
	/**
	 * The title of the episode.
	 */
	private String title;
	
	/**
	 * The overview of the episode
	 */
	private String overview;
	
	/**
	 * The air date of the episode.
	 */
	private Date firstAired;
	
	/**
	 * URL of the episode.
	 */
	private URL url;
	
	/**
	 * Watched status of the episode
	 */
	private boolean watched = false;
	
	/**
	 * Favourite flag for the episode
	 */
	private boolean favorite = false;

	/**
	 * Image for the episode
	 */
	private ICoverArt image;

	/**
	 * Instantiate a new episode by episode number and title.
	 * @param number the Episode number
	 * @param seasonNumber the season number
	 * @param title
	 */
	public Episode(int number, int seasonNumber, String id, String title){
		this.number = number;
		this.title = title;
		this.seriesId = id;
		this.seasonNumber = seasonNumber;
	}

	/**
	 * Add the episode to the favourites
	 */
	public void addToFavorites() {
		this.favorite = true;
	}
	
	/**
	 * Remove the episode from the favourites
	 */
	public void removeFromFavorites() {
		this.favorite = false;
	}

	/**
	 * Check if the episode has been favourited
	 */
	public boolean isInFavorites() {
		return this.favorite;
	}

	/**
	 * Mark the episode as watched
	 */
	public void setWatched() {
		this.watched = true;
	}

	/**
	 * Mark the episode as not watched
	 */
	public void setUnWatched() {
		this.watched = false;
	}

	/**
	 * Check if the episode has been watched.
	 */
	public boolean isWatched() {
		return this.watched;
	}

	/**
	 * The consecutive number of the episode in the season.
	 * @return the number
	 */
	public int getNumber() {
		return number;
	}

	/**
	 * Set consecutive number of the episode in the season.
	 * @param the number
	 */
	public void setNumber(int number) {
		this.number = number;
	}

	/**
	 * Get the title of the episode.
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * Set the title of the episode.
	 * @param title the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * Get the overview of the episode
	 * @return the overview
	 */
	public String getOverview() {
		return overview;
	}

	/**
	 * Set the overview of the episode
	 * @param overview the overview to set
	 */
	public void setOverview(String overview) {
		this.overview = overview;
	}

	/**
	 * Get the air date of the episode
	 * @return the firstAired date of the episode
	 */
	public Date getFirstAired() {
		return firstAired;
	}

	/**
	 * Set the air date of the episode
	 * @param firstAired the firstAired to set
	 */
	public void setFirstAired(Date firstAired) {
		this.firstAired = firstAired;
	}

	/**
	 * Get the URL of the episode
	 * @return the url
	 */
	public URL getUrl() {
		return url;
	}

	/**
	 * Set the URL of the episode
	 * @param url the url to set
	 */
	public void setUrl(URL url) {
		this.url = url;
	}

	/**
	 * Get the image of the episode
	 * @return the image
	 */
	public ICoverArt getImage() {
		return image;
	}

	/**
	 * Set the image of the episode
	 * @param image the image to set
	 */
	public void setImage(Bitmap image) {
		this.image = new CoverArtFromImage(image);
	}
	
	/**
	 * Set the image of the episode
	 * @param url of the image to set
	 * @throws MalformedURLException 
	 */
	public void setImage(String url) throws MalformedURLException {
		this.image = new CoverArtFromURL(url);
	}
	
	/**
	 * @return the seasonNumber
	 */
	public int getSeasonNumber() {
		return seasonNumber;
	}

	/**
	 * @param seasonNumber the seasonNumber to set
	 */
	public void setSeasonNumber(int seasonNumber) {
		this.seasonNumber = seasonNumber;
	}

	/**
	 * @return the seriesId
	 */
	public String getSeriesId() {
		return seriesId;
	}

	/**
	 * @param seriesId the seriesId to set
	 */
	public void setSeriesId(String seriesId) {
		this.seriesId = seriesId;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + number;
		result = prime * result + seasonNumber;
		result = prime * result
				+ ((seriesId == null) ? 0 : seriesId.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Episode other = (Episode) obj;
		if (number != other.number)
			return false;
		if (seasonNumber != other.seasonNumber)
			return false;
		if (seriesId == null) {
			if (other.seriesId != null)
				return false;
		} else if (!seriesId.equals(other.seriesId))
			return false;
		return true;
	}
	
	/* (non-Javadoc)
	 * @see ITitle#compareTo(ITitle)
	 */
	public int compareTo(Episode ep) {
		int result = seriesId.compareTo(ep.getSeriesId());
		
		if (result == 0) {
			result = new Integer(this.getSeasonNumber())
							.compareTo(ep.getSeasonNumber());
			if (result == 0) {
				result =
						new Integer(this.getNumber()).compareTo(ep.getNumber());
			}
		}
		return result;
	}
	
}
